package elephant.rpc.server.session;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import elephant.rpc.server.message.RPCMessage;

/**
 * 
 * @author skydu
 *
 */
public class RPCSessionManager {
	private static Logger logger=LoggerFactory.getLogger(RPCSessionManager.class);
	//
	private Map<Integer,RPCSession>sessionMap;
	private AtomicInteger sessionId;
	//
	public RPCSessionManager() {
		sessionMap=new ConcurrentHashMap<>();
		sessionId=new AtomicInteger();
	}
	//
	public void sessionCreated(RPCSession session){
		synchronized (session) {
			sessionCreated0(session);
		}
	}
	//
	private void sessionCreated0(RPCSession session){
		int nextSessionId=sessionId.incrementAndGet();
		session.id=nextSessionId;
		if(logger.isDebugEnabled()){
			logger.debug("session created session id:{}/host{}:{}"+
					session.id,
					session.remoteHost,
					session.remotePort);
		}
		//
		sessionMap.put(session.id,session);
	}
	//
	public void sessionDisconnected(RPCSession session){
		synchronized (session) {
			sessionDisconnected0(session);
		}
	}
	//
	private void sessionDisconnected0(RPCSession session){	
		if(logger.isDebugEnabled()){
			logger.debug("session disconnected session id:{}/host{}:{}"+
					session.id,
					session.remoteHost,
					session.remotePort);
		}
		sessionMap.remove(session.id);
	}
	//
	public RPCSession getSessionById(int id){
		return sessionMap.get(id);
	}
	//
	public int getSessionCount(){
		return sessionMap.size();
	}
	//
	public List<RPCSession>getSessions(){
		return new ArrayList<>(sessionMap.values());
	}
	//
	public void publish(String topic,String serviceId,Object payload) {
		sessionMap.values().forEach(session->{
			if(session.topics.contains(topic)){
				RPCMessage msg=new RPCMessage();
				msg.type=RPCMessage.TYPE_PUSH;
				msg.payloads=new Object[]{serviceId,payload};
				session.write(msg);
			}
		});
	}
	//
}
